package logger

import (
	"io"
	"os"

	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

/*
	TODO :1.从配置文件来决定用什么 encoder 这里先使用 json
*/
// log 输出编码配置！
func setEncoder() zapcore.Encoder {
	encodeConfig := zap.NewProductionEncoderConfig()
	encodeConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encodeConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	return zapcore.NewJSONEncoder(encodeConfig)
}

/*
setIoWriter

	stdout   是否需要标准输出到控制台
	filename 输出到的文件路径
	TODO feature 全部参数化！
*/
func setIoWriter(stdout bool, filename string) zapcore.WriteSyncer {
	lg := &lumberjack.Logger{
		Filename:   filename,
		MaxSize:    10,
		MaxBackups: 10,
		MaxAge:     7,
		Compress:   true,
	}
	var ws io.Writer
	if stdout {
		ws = io.MultiWriter(lg, os.Stdout)
	} else {
		ws = lg
	}
	return zapcore.AddSync(ws)
}

func InitLogger(debugPath string, errPath string) (logger *zap.Logger, err error) {
	/*
		DebugLevel 等级的日志输出包括了 ERROR 等级, 同样可以把ERROR的同时输出到控制台和默认文件
		所以下面的ErrorLevel 只需要输出到文件中就可以了！
	*/

	// 读取配置基础日志级别,支持将 字符串 转换为 zap.Level 类型~
	level := new(zapcore.Level)
	err = level.UnmarshalText([]byte("DEBUG"))
	if err != nil {
		return nil, err
	}
	coreDebug := zapcore.NewCore(setEncoder(), setIoWriter(true, debugPath), level)
	coreError := zapcore.NewCore(setEncoder(), setIoWriter(false, errPath), zap.ErrorLevel)
	core := zapcore.NewTee(coreDebug, coreError)
	logger = zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1))
	return logger, nil
}
